package com.game.my2048;


import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Point;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by Administrator on 16-8-16.
 */

/*
* 这是作者创建的一个View,使用网格布局
* */
public class GameView extends GridLayout {
    public GameView(Context context) {
        super(context);
        init();
    }


    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        setColumnCount(4);

        setOnTouchListener(new OnTouchListener() {
            private float startX, startY, offsetX, offsetY;
            /*
            * offsetX   在X轴上移动的值    为正则是向右边
            *                           为负则是向左边
            * offsetY   同offsetX一样
            *
            * */
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) { //这个是判断当前的状态
                    case MotionEvent.ACTION_DOWN://这个为刚刚按下去的时候
                        startX = event.getX();
                        startY = event.getY();
                        break;

                    case MotionEvent.ACTION_UP://这个为松开的时候
                        offsetX = event.getX() - startX;
                        offsetY = event.getY() - startY;

                        boolean isHorizontal = Math.abs(offsetX) > Math.abs(offsetY);

                        if (isHorizontal) {
                            if (offsetX > 10) {
                                scrollRight();
                            } else if (offsetX < -10) {
                                scrollLeft();
                            }

                        } else {
                            if (offsetY > 10) {
                                scrollDown();
                            } else if (offsetY < -10) {
                                scrollUp();
                            }
                        }
                        break;

                }
                return true;
            }
        });
    }

    //第一次执行，屏幕大小不变则不执行
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        int cardWidth = (Math.min(w, h) - 10) / 4;
        createCard(cardWidth, cardWidth);
        startGame();
    }
    //我觉得应该叫 createCard 然后传入Width,Height
//    private void addCard(int cardWidth, int cardHeight) {
    private void createCard(int cardWidth, int cardHeight) {
        Card c;
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                c = new Card(getContext());
                c.setNum(0);
                addView(c, cardWidth, cardHeight);
                cardMap[x][y] = c;
            }
        }


    }
    //开始游戏
    private void startGame() {
        //这里将MainActivity中的值进行初始化,比分为0
        MainActivity.getMainActivity().clearScore();
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                cardMap[x][y].setNum(0);
            }
        }

        //然后随机在屏幕上随机两个数出来
        addRandomNum();
        addRandomNum();
    }
    // 将剩余位置放置了随机数  2,4
    private void addRandomNum() {

        emptyPoints.clear();
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                if (cardMap[x][y].getNum() <= 0) {
                    emptyPoints.add(new Point(x, y));
                }
            }
        }
        Point p = emptyPoints.remove((int) (Math.random() * emptyPoints.size()));
//        cardMap[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4);
        //原来作者是大于等于0.1  这是不对等的随机取数。我改成了0.5
        cardMap[p.x][p.y].setNum(Math.random() > 0.5 ? 2 : 4);
    }

    /*
    * 这个四个函数分别处理
    * 四种情况其中将向左滑动进行了注释
    * */

    private void scrollLeft() {
        boolean isMerge = false;//该参数的意义是知道是否发送了合并操作
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                for (int x1 = x + 1; x1 < 4; x1++) {

                    if (cardMap[x1][y].getNum() > 0) {
                        if (cardMap[x][y].getNum() <= 0) {
                            cardMap[x][y].setNum(cardMap[x1][y].getNum());
                            cardMap[x1][y].setNum(0);
                            x--;    //这个地方很重要,有一个回溯的意思
                            isMerge = true;
                        } else if (cardMap[x][y].getNum() == cardMap[x1][y].getNum()) {
                            cardMap[x][y].setNum(cardMap[x][y].getNum() * 2);
                            cardMap[x1][y].setNum(0);
                            isMerge = true;
                            //这里更新分数
                            MainActivity.getMainActivity().addScore(cardMap[x][y].getNum());

                        }
                        break;
                    }
                }
            }
        }
        if (isMerge) {
            addRandomNum();
            checkComplete();
        }
    }

    private void scrollRight() {
        boolean merge = false;
        for (int y = 0; y < 4; y++) {
            for (int x = 3; x >= 0; x--) {
                for (int x1 = x - 1; x1 >= 0; x1--) {
                    if (cardMap[x1][y].getNum() > 0) {
                        if (cardMap[x][y].getNum() <= 0) {
                            cardMap[x][y].setNum(cardMap[x1][y].getNum());
                            cardMap[x1][y].setNum(0);
                            x++;
                            merge = true;
                        } else if (cardMap[x][y].getNum() == cardMap[x1][y].getNum()) {
                            cardMap[x][y].setNum(cardMap[x][y].getNum() * 2);
                            cardMap[x1][y].setNum(0);
                            merge = true;
                            MainActivity.getMainActivity().addScore(cardMap[x][y].getNum());
                        }
                        break;
                    }
                }
            }
        }
        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

    private void scrollUp() {
        boolean merge = false;
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                for (int y1 = y + 1; y1 < 4; y1++) {
                    if (cardMap[x][y1].getNum() > 0) {
                        if (cardMap[x][y].getNum() <= 0) {
                            cardMap[x][y].setNum(cardMap[x][y1].getNum());
                            cardMap[x][y1].setNum(0);
                            y--;
                            merge = true;
                        } else if (cardMap[x][y].getNum() == cardMap[x][y1].getNum()) {
                            cardMap[x][y].setNum(cardMap[x][y].getNum() * 2);
                            cardMap[x][y1].setNum(0);
                            merge = true;
                            MainActivity.getMainActivity().addScore(cardMap[x][y].getNum());
                        }
                        break;
                    }
                }
            }
        }
        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

    private void scrollDown() {

        boolean merge = false;
        for (int x = 0; x < 4; x++) {
            for (int y = 3; y >= 0; y--) {
                for (int y1 = y - 1; y1 >= 0; y1--) {
                    if (cardMap[x][y1].getNum() > 0) {
                        if (cardMap[x][y].getNum() <= 0) {
                            cardMap[x][y].setNum(cardMap[x][y1].getNum());
                            cardMap[x][y1].setNum(0);
                            y++;
                            merge = true;
                        } else if (cardMap[x][y].getNum() == cardMap[x][y1].getNum()) {
                            cardMap[x][y].setNum(cardMap[x][y].getNum() * 2);
                            cardMap[x][y1].setNum(0);
                            merge = true;
                            MainActivity.getMainActivity().addScore(cardMap[x][y].getNum());
                        }
                        break;
                    }

                }
            }
        }
        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }
    //游戏结束了判断
    private void checkComplete() {

        boolean complete = true;
        Out:
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                if (cardMap[x][y].getNum() == 0 ||
                        (x > 0 && cardMap[x][y].getNum() == cardMap[x - 1][y].getNum()) ||
                        (x < 3 && cardMap[x][y].getNum() == cardMap[x + 1][y].getNum()) ||
                        (y > 0 && cardMap[x][y].getNum() == cardMap[x][y - 1].getNum()) ||
                        (y < 3 && cardMap[x][y].getNum() == cardMap[x][y + 1].getNum())) {
                    complete = false;
                    break Out;
                }
            }
        }
        if (complete) {
            new AlertDialog.Builder(getContext()).setTitle("Hello！").setMessage("Game Over!")
                    .setPositiveButton("Try again", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startGame();
                        }
                    }).setCancelable(false).
                    show();
        }
    }

    private Card[][] cardMap = new Card[4][4];
    private List<Point> emptyPoints = new ArrayList<Point>();

}

